package runnerworm.core;

import java.awt.*;

/**
 * <p>Title: WormThread</p>
 * <p>Description: This class will make the worm run, which is the game's objective.
 * When the worm moves, it has to be redrawn, so it redraws the worm too.</p>
 * @author Guilherme Mauro Germoglio Barbosa
 */

public class WormThread
    extends Thread {

  /**
   * The worm this thread will make run.
   */
  private Worm worm;
  /**
   * Where the worm will be drawn
   */
  private Graphics graphics;
  /**
   * The translation coeficient used on its movement.
   */
  private double y1;
  /**
   * The "side" coeficient used on its movement.
   */
  private double a;
  /**
   * The world famous "x" coordinate. Where the worm will be on the tunnel - or it
   * thinks it is.
   */
  private double x;
  /**
   * The world famous "y" coordinate. Where the worm will be on the tunnel - or it
   * thinks it is.
   */
  private double y;
  /**
   * Where the worm head will be on the screen - the y coordinate.
   */
  private double y_screen;

  /**
   * If the worm was going up.
   */
  private boolean wasGoingUp;

  /**
   * Will make this thread ready to start.
   * @param worm The worm.
   * @param graphics The graphics.
   */
  public WormThread(Worm worm, Graphics graphics) {
    this.worm = worm;
    this.graphics = graphics;
    y1 = - worm.get_Y_head();
    a = 1;
    x = 0;
    y = worm.get_Y_head();
    wasGoingUp = worm.isGoingUp();
  }

  /**
   * The thread behavior. Will draw the worm, wait a few milliseconds, erase the worm
   * and move it, until the worm die.
   */
  public void run() {
    while (worm.isAlive()) {
      show();
      // move
      move();
    }
  }

  /**
   * Shows the worm.
   */
  public synchronized void show() {
    // draw
    worm.draw(graphics);
    // wait
    try {
      sleep(24);
    }
    catch (InterruptedException e) {
      System.out.println("Holly shit!");
    }
    // erase
    worm.erase(graphics);
  }

  /**
   * Moves the worm, according if it's going up, down... blah.
   */
  public synchronized void move() {
    // invert the movement, if necessary
    if (wasGoingUp != worm.isGoingUp()) {
      wasGoingUp = worm.isGoingUp();
      a = -1 * a;
      x = -1 * x;
      y1 = (a * Math.pow(x, 2)) - y_screen;
    }
    // moves, baby
    y = a * Math.pow(x, 2);
    y_screen = y - y1;
    worm.moveHead(worm.get_X_head(), y_screen);
    x = x + 0.3;
  }
}